## 待修改： group_levels_in_order_C <- group_levels_ordered
# 待删除函数：compare_mutile_groups() 太矬了，函数名还拼错了

library("pacman")
p_load("dplyr")
p_load("plyr")
p_load("ggplot2")
p_load("stringr")
p_load("reshape2")
p_load("PMCMR")
p_load("ggforce")
p_load(openxlsx)
p_load(Loafer)
# data(iris)


#' @title univariate compare between two or more groups
#' @param input_df data frame. sample in each row. sample name are rownames
#' @param group_info_df group info df. sample names are rownames
#' @param group_index group index (num) or group-colname(character) in group_info_df.
#' @param group_levels_in_order_C set group as ordered factors. 
#' Also, this param can subset the groups paticipate for the test.
#' @param test_pattern one of "wise", "para" and "non-para". to choose the test pattern. 
#' @param p_for_label parameter for add_labels_into_result_df function. choose from "p_all", "pairwise_p.raw", and "pairwise_p.adj".
#' @param position_by "max meanse" or "max_single_value". Get labels position by mean+sd or by max value.
#' @param draw_pics wether to draw the pictures.
#' @param unify_step_as_constant T/F. Use same (fixed constant) / different (ratio * range) distances for steps among variables.
#' @param step numeric. vertial distance between significant labels.
#' @param drap_pics T/F. Wether to draw plots with default settings. 
#' @param get_step_by_max_instead_of_range T/F. This function were mainly utilized to show non-negetive values. Thus, steps generated by max value instead of range(max-min) may be better.
#' @return 
#' @export


get_pic_with_labels <- function(input_df = iris[,1:4],
                                # input_df$Sepal.Length <- rnorm(nrow(input_df)),
                                group_info_df = iris[,5,drop = F],
                                group_index = 1,
                                group_levels_in_order_C = group_info_df[,1] %>% unique(),
                                test_pattern  = "para" ,
                                # test_pattern  = "wise" ,
                                # test_pattern  = "non-para" %>% tolower(),
                                p_for_label = "p_all",
                                step = 0.05,
                                group_pairs_to_show = NULL,
                                unify_step_as_constant = F,
                                get_step_by_max_instead_of_range = T,
                                draw_pics = F, 
                                position_by = "max single value"){
    { # initialize the object for analysis.
        setClass("obj_for_analysis", 
                 slots = list(input_df = "data.frame", ## input raw data.
                              group_info_df = "data.frame", ## input group information.
                              df_for_test = "data.frame", ## data to be used for compare.
                              ## group order to be shown in pic.
                              group_levels_in_order_C ="vector",
                              step = "numeric",
                              
                              p_for_label = "character",  ## generate label based on chosen p 
                              test_pattern = "character",
                              demo_code = "character",
                              demo_code_for_barplot = "character",
                              ## output results:
                              result_df = "data.frame", ## Compare results, P and label. Data results
                              ## data.frame for plot:
                              unify_step_as_constant = "vector",
                              get_step_by_max_instead_of_range = "vector",
                              unify_step_by_max_range = "numeric",
                              max_value_overall = "numeric",
                              
                              pic_long_df = "data.frame", ## df for points in pic.
                              label_position_df = "data.frame" ## df for labels and position in pic. 
                 ))

        
        group_info_df <- group_info_df[,group_index] %in% group_levels_in_order_C %>% group_info_df[.,,drop = F]
        input_df  <- rownames(group_info_df) %>% input_df[.,,drop = F] ## reorder the input_df.
        colnames(group_info_df)[group_index] <- "group"
        df_for_test <- data.frame(group = group_info_df[,group_index], input_df, 
                                  check.names = F, stringsAsFactors = F)
        
        
        
        
        obj <- new("obj_for_analysis",
                   df_for_test = df_for_test,
                   input_df = input_df,
                   step = step,
                   unify_step_as_constant = unify_step_as_constant,
                   get_step_by_max_instead_of_range = get_step_by_max_instead_of_range,
                   p_for_label = p_for_label,
                   group_levels_in_order_C = group_levels_in_order_C,
                   # group_index = group_index,
                   test_pattern = test_pattern %>% tolower(),
                   group_info_df = group_info_df )
        ## get the data used for the later test.
    }
    
    obj <- compare_by_col(obj)
    
    ## get long_df for pic
    obj <- get_long_df(obj)
    obj <- add_labels_into_result_df(obj)
    
    obj <- get_label_position_df(obj)
    # obj@label_position_df
    
    ## keep compares between selected groups and remove others.
    # obj@label_position_df
    
    if(length(group_pairs_to_show) != 0){
        obj <- subset_group_pairs(obj = obj, group_pairs_to_show = group_pairs_to_show)
    }
    
    obj@label_position_df
    if(position_by == "max meanse"){
        obj <- get_position_by_max_meanse(obj)
    } else {
        obj <- get_position_by_max_single_value(obj)
    }
    
    obj@label_position_df <- (obj@label_position_df$label != "   ") %>% obj@label_position_df[.,]
    obj <- draw_plot_with_labels(obj, draw_pics = draw_pics)
    obj <- get_demo_codes_for_bar_plots(obj)
    cat("\n\nTry >>'cat(obj@demo_code)'<< to see the code for boxplot visualization.
           \nTry >>'cat(obj@demo_code_for_barplot)'<< to see the code for barplot\n
        obj means the obj returned by this function.")
    
    ## order the group variable for plot
    obj@pic_long_df$group <- obj@pic_long_df$group %>% 
        factor(., levels = group_levels_in_order_C, ordered = T)
    
    
    obj@label_position_df$variable <- obj@label_position_df$variable %>% 
        factor(., levels = obj@pic_long_df$variable %>% levels, ordered = T)
    return(obj)
}


# body(get_plot_with_labels) 

## examples
if(F){
    "Demo to start with"    
    ## application of the function.
    data(iris)
    
    # colnames(iris)
    if(F){
        input_df = iris[,1:4]
        input_df = iris[,1, drop = F]
        input_df$Sepal.Length <- rnorm(nrow(input_df))
        
        group_info_df = iris[,5,drop = F]
        group_index = 1
        group_levels_in_order_C = group_info_df[,1] %>% unique()
        test_pattern  = "para" 
        test_pattern  = "wise" 
        test_pattern  = "non-para" %>% tolower()
        p_for_label <- "p_all"
        step = 0.05
        position_by = "max single value"
        
        draw_pics = F
    }
    
    # obj <- get_pic_with_labels(input_df = iris[,1:3],
    obj <- get_pic_with_labels(input_df = iris[,1,drop = F],
                               # input_df$Sepal.Length <- rnorm(nrow(input_df)),
                               group_info_df = iris[,5,drop = F],
                               group_index = 1,
                               group_levels_in_order_C = group_info_df[,1] %>% unique(),
                               test_pattern  = "para" ,
                               # test_pattern  = "wise" ,
                               # test_pattern  = "non-para" %>% tolower(),
                               p_for_label = "p_all",
                               step = 0.05,
                               draw_pics = F, 
                               position_by = "max single value")
    
    obj@result_df # P-value result.
    obj@label_position_df # df for labeling in the plot.
    cat(obj@demo_code)
    
    
    
}

